home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / terms / kermit / b / ckmusr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-30  |  52.0 KB  |  2,105 lines

  1. /* $Id: ckmusr.c,v 1.10 91/12/27 21:49:54 fdc Exp $
  2.  * $Source: /uw/mackermit/RCS/ckmusr.c,v $
  3.  *------------------------------------------------------------------
  4.  * $Log:    ckmusr.c,v $
  5.  * Revision 1.10  91/12/27  21:49:54  fdc
  6.  * Change fatal to macfatal.
  7.  * 
  8.  * Revision 1.9  91/12/15  23:17:58  rick
  9.  * ut9
  10.  * 
  11.  * Revision 1.8  91/10/13  13:43:43  rick
  12.  * UT(7)
  13.  * 
  14.  * Revision 1.7  91/10/01  12:17:15  rick
  15.  * UT(5)
  16.  * 
  17.  * Revision 1.6  91/09/25  12:17:43  rick
  18.  * Command window in TE. Multiple vt100 windows for command window.
  19.  * 
  20.  * Revision 1.5  91/09/12  21:50:56  rick
  21.  * UT(3). Install on watsun
  22.  * 
  23.  * Revision 1.4  1991/09/12  19:08:35  rick
  24.  * Cleanups.
  25.  *
  26.  * Revision 1.3  1991/09/12  16:43:13  rick
  27.  * Cleanups.
  28.  *
  29.  * Revision 1.2  1991/09/10  22:21:50  rick
  30.  * Update to UTexas(2)
  31.  *
  32.  * Revision 1.1  1991/09/10  19:18:08  rick
  33.  * Initial revision
  34.  *
  35.  *------------------------------------------------------------------
  36.  * $Endlog$
  37.  */
  38.  
  39. /*
  40.  edit by John A. Oberschelp for Emory University --
  41.  vt102 printer support 22 May 1989
  42.  */
  43. /* Emory contact is Peter W. Day, ospwd@emoryu1.cc.emory.edu */ 
  44. /* various edits by PWP 8/88 -- 5/89: much rearangement, new menus 'n stuff */
  45. /* edit by PWP 3/27/88 -- Make the log session and transaction stuff a   */
  46. /*  separate menu. */
  47. /* edits by PWP -- Nov. 87..Mar. 88  Fixed several oversights, bugs, etc., */
  48. /* added MultiFinder support */
  49. /* Version 0.9(36) - Matthias Aebi, ECOFIN Research and Consulting, Ltd., */
  50. /*  Oct 1987 ported to MPW C */
  51. /* Version 0.8(35) - Jim Noble at Planning Research Corporation, June 1987. */
  52. /* Ported to Megamax native Macintosh C compiler. */
  53. /* DPVC at U of R, on Oct 1, to do blinking cursor and mouse cursor movement */
  54. /* Edit by Bill, Jeff, and Howie on Jun 13 */
  55. /* Add select window, drag */
  56. /* Edit by WBC3 on Apr 29 */
  57. /* Don't supply a second name for send as, otherwise file name translation */
  58. /* will not occur.  Let user type it if they want. */
  59. /* Edit by WBC3 on Apr 23 */
  60. /* Make typein to the emulator only take effect when it's the "front window" */
  61. /* Edit by WBC3 on Apr 23 */
  62. /* Make only Command-. stop protocol rather then anything but Command-. */
  63. /* Edit by WBC3 on Apr 22 */
  64. /* Make debug and tlog only show up if DEBUG is defined */
  65. /* Edit by Bill on Apr 21 17:51 */
  66. /* In Screen depelete event queue instead of handling one event at */
  67. /* a time, also don't loose events */
  68.  
  69. /*
  70.  * file ckmusr.c
  71.  *
  72.  * Module of mackermit containing code for the menus and other MacIntosh
  73.  * things.
  74.  *
  75.  */
  76.  
  77. /*
  78.   Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
  79.   York.  Permission is granted to any individual or institution to use this
  80.   software as long as it is not sold for profit.  This copyright notice must be
  81.   retained.  This software may not be included in commercial products without
  82.   written permission of Columbia University.
  83. */
  84.  
  85. #include <DiskInit.h>
  86. #include "ckcdeb.h"
  87. #include "ckcker.h"
  88.  
  89. #include "ckmdef.h"        /* General Mac defs */
  90. #include "ckmres.h"        /* Mac resource equates */
  91. #include "ckmasm.h"        /* new A8 and A9 traps */
  92. #include "ckmwin.h"        /* common window routines */
  93. #include "ckmcon.h"
  94. #include "ckmptp.h"        /* ckm* Prototypes */
  95.  
  96. /* Global Variables */
  97.  
  98. int success = 1;        /* C-Kermit command succeeded flag */
  99. int cmdlvl = 0;            /* macro nesting depth (currently unused) */
  100.  
  101. #ifdef CK5A
  102. /* file wierdness (used for VAX/VMS C-Kermit */
  103. int fblksiz = DBLKSIZ;        /* file block size */
  104. int frecl = DLRECL;        /* file record length */
  105. int frecfm = XYFF_S;        /* file record format */
  106. int forg = XYFO_S;        /* file orginization (sequential) */
  107. int fcctrl = XYFP_N;        /* file carriage control (control chars) */
  108. #endif /* CK5A */
  109.  
  110. MenuHandle menus[LAST_MENU + 1];/* handle on our menus */
  111.  
  112. short innum;            /* Input driver refnum */
  113. short outnum;            /* Output driver refnum */
  114. int protocmd;            /* protocol file cmd, or -1 for */
  115.  /* remote cmds, or 0 if not in */
  116.  /* protocol */
  117.  
  118. char *mybuff;            /* Serial drivers new buffer */
  119.  
  120. SerShk controlparam;        /* To change serial driver paramaters */
  121.  
  122. int quit = FALSE;
  123.  
  124. Boolean mcmdactive = TRUE;    /* Enable menu command keys */
  125. Boolean fkeysactive = TRUE;    /* Enable FKEYs */
  126.  
  127. #ifdef notdef
  128. extern WindowPtr remoteWindow;    /* the remote command window */
  129. #endif
  130.  
  131. extern int deblog;        /* if true, do debugging */
  132. extern int connected;
  133. extern OSType texttype;
  134. extern OSType kermtype;
  135. extern Cursor *lastCursor, *watchcurs;
  136.  
  137. /* 
  138.  * local variables 
  139.  */
  140. static int titlen = 1;
  141. Boolean have_multifinder = FALSE; /* becomes true if we are running MF */
  142. Boolean in_background = FALSE;    /* becomes TRUE if have_multifinder and
  143.                  * we have recieved a "suspend" event */
  144.  
  145. long mf_sleep_time = 3L;    /* this is the number of (60Hz) ticks to
  146.                  * sleep before getting a nullEvent (to
  147.                  * flash our cursor) (and input chars from
  148.                  * the serial line)
  149.                  */
  150. Boolean have_128roms = FALSE;    /* actually, a Mac + or better */
  151. #define switchEvt     1 /* Switching event (suspend/resume )  for app4evt */
  152.  
  153. /*
  154.  * Stuff for alarm() and friends.
  155.  */
  156. #define SIGTYP long
  157. #define SIG_IGN 0
  158. #define SIGALRM 1
  159. #define SIGINT 2
  160. SIGTYP (*msignal(int type, SIGTYP (*func)(int)))(int);
  161. SIGTYP (*alarmfunc)() = SIG_IGN;
  162. SIGTYP (*intfunc)() = SIG_IGN;
  163. typedef unsigned long ulong;
  164. ulong alarmtime = 0;          /* global alarm time */
  165.  
  166. /*
  167.  * Forward reference
  168.  */
  169. void updateCursor();
  170. char *malloc_pstring(char *);
  171. void closecmdw (struct cmdw *cmdw);
  172. Boolean checksave (struct cmdw *cmdw);
  173.  
  174. /*
  175.  * Externals
  176.  */
  177. extern Handle hPrintBuffer;            /*JAO*/
  178. extern long lPrintBufferChars;
  179. extern long lPrintBufferAt;
  180. extern struct cmdw *activecmdw;
  181. extern struct cmdw *cmdwl;
  182. extern int to_printer;
  183.  
  184. #ifdef notdef
  185. /****************************************************************************/
  186. /*
  187.  *  m a c p a r s e r
  188.  *
  189.  *  Entry point for kermit.
  190.  *  Establish a virtual terminal connection with the remote host and
  191.  *  process mouse events, such as selecting items from the menu bars.
  192.  *
  193.  */
  194. /****************************************************************************/
  195. char
  196. macparser ()
  197. {
  198.     int sconnected;
  199.     char menu_event ();
  200.     char domouse ();
  201.     char nextcmd ();
  202.     char rstate = 0;
  203.     EventRecord myevent;
  204.     struct cmdw *cmdw;
  205.  
  206. #ifdef notdef                /***** IS THIS EVER USED? *****/
  207.     if (tlevel > -1) {            /* if we are working under take-file */
  208.     rstate = nextcmd ();        /* file control, get next command */
  209.     if (!quit)
  210.         return (rstate);
  211.     }
  212. #endif
  213.     protocmd = 0;            /* protocol not active */
  214.     updateCursor(ttermw, 1, NIL);    /* back to normal cursor */
  215.     
  216.     /*
  217.      * Save state of connected.  If it changes, exit macparser().
  218.      */
  219.     sconnected = connected;
  220.  
  221.     while (!(quit || rstate)) {        /* Until they want to quit */
  222.     if (sconnected != connected)
  223.         return (rstate);
  224.  
  225.     /* or return */
  226.     if (!have_multifinder)        /* MF does this for us */
  227.         SystemTask ();        /* Update system things */
  228.  
  229.     /* Handle all the pending port chars */
  230.     inpchars(ttermw);
  231.  
  232.     if (have_multifinder) {
  233.         /* task, task */
  234.         /*
  235.          * NOTE: mf_sleep_time MUST be < 50 to work right, due to
  236.          * a bug in MultiFinder 1.0.  See TN 177.
  237.          */
  238.         if (mf_sleep_time > 30L)
  239.             mf_sleep_time = 30L;
  240.         WaitNextEvent (everyEvent, &myevent, mf_sleep_time, NULL);
  241.     } else {
  242.         GetNextEvent (everyEvent, &myevent);
  243.     }
  244.     
  245.     switch (myevent.what) {        /* events */
  246.     case keyDown:            /* Handle char input */
  247.     case autoKey:            /* both ways */
  248.         if ((myevent.modifiers & cmdKey) && (mcmdactive)) {
  249.         rstate = menu_event (MenuKey (myevent.message & charCodeMask));
  250.         } else if (FrontWindow () == ttermw->window) {
  251.         if (!connected) {
  252.             if (console_char(ttermw, &myevent)) {
  253.             updateCursor(ttermw, 1, NIL); /* set the watch */
  254.             return (rstate); /* and return with state */
  255.             }
  256.         }
  257.         else {
  258.             handle_char (ttermw, &myevent);
  259.             if (sconnected != connected)
  260.             return (rstate);
  261.         }
  262.         } else if (cmdw = cmdwbywindow(FrontWindow())) {
  263.         rcdkey(cmdw, &myevent);
  264.         } else if (FrontWindow () == ctermw->window) {
  265.         /* always a command in this window */
  266.         if (console_char(ctermw, &myevent)) {
  267.             updateCursor(ctermw, 1, NIL); /* set the watch */
  268.             return (rstate); /* and return with state */
  269.         }
  270.         }
  271.         break;
  272.  
  273.     case updateEvt:            /* A window update event */
  274.         doupdate ((WindowPtr) myevent.message); /* Handle update */
  275.         break;
  276.  
  277.     case activateEvt:        /* (de)active a window */
  278.         doactivate ((WindowPtr) myevent.message, myevent.modifiers);
  279.         break;
  280.  
  281.     case mouseDown:            /* Mouse event */
  282.         rstate = domouse (&myevent, FALSE);
  283.         break;
  284.  
  285.     case app4Evt:            /* could be a suspend/resume event */
  286.         if ((have_multifinder) &&
  287.             (((myevent.message >> 24) & 0xff) == switchEvt)) {
  288.         in_background = ((myevent.message & 0x1) == 0);
  289.         /* do suspend things */
  290.         }
  291.         updateCursor(ttermw, 1, myevent.message);
  292.         break;
  293.     } /* switch */
  294.     
  295.     if (ttermw->blinkcursor)        /* PWP: save some time */
  296.         flash_cursor (ttermw); /* (UoR) for flashing cursor */
  297.  
  298.     updateCursor(ttermw, 0, NIL);
  299.     } /* while */
  300.  
  301.     if (quit)                /* want to exit the program? */
  302.     doexit (GOOD_EXIT,-1);        /* yes, finish up */
  303.  
  304.     updateCursor(ttermw, 1, NIL);        /* set the watch */
  305.     return (rstate);            /* and return with state */
  306. }                    /* parser */
  307. #endif
  308.  
  309.  
  310. /****************************************************************************/
  311. /* miniparser - called during protocol to handle events.  Handles dialog, */
  312. /*                  update, and keydown (the abort key) events.  Ignores */
  313. /*                  all other events.  The dialog events are assumed to */
  314. /*                  be for screen (status) display. */
  315. /****************************************************************************/
  316. miniparser (deplete)        /* deplete pending events */
  317. {
  318.     EventRecord ev;
  319.     DialogPtr mydlg;
  320.     short item;
  321.     
  322.     do {
  323.     if (have_multifinder) {
  324.         /* task, task */
  325.         /*
  326.          * NOTE: mf_sleep_time MUST be < 50 to work right, due to
  327.          * a bug in MultiFinder 1.0.  See TN 177.
  328.          */
  329.         if (mf_sleep_time > 30L)
  330.             mf_sleep_time = 30L;
  331.         WaitNextEvent (everyEvent, &ev, mf_sleep_time, NULL);
  332.     } else {
  333.         SystemTask ();    /* let the system move */
  334.         GetNextEvent (everyEvent, &ev);    /* get an event */
  335.     }
  336.  
  337.     /*
  338.      * Be paranoid: check for all the events that IsDialogEvent might trap
  339.      * but we want to do something with anyway FIRST.
  340.      */
  341.     switch (ev.what) {    /* we may need to do something */
  342.       case nullEvent:
  343.         return;        /* we have depleted all pending events */
  344.  
  345.       case keyDown:
  346.         if ((ev.modifiers & cmdKey) && ((ev.message & 0x7f) == '.')) {
  347.         if (CautionAlert (ALERT_ABORT, 
  348.                   (ModalFilterProcPtr) NILPROC) == OKBtn) {
  349.             sstate = 'a';    /* move into abort state */
  350.             return;
  351.         }
  352.         }
  353.         break;
  354.  
  355.       case app4Evt:    /* really a suspend/resume event */
  356.         if ((have_multifinder) &&
  357.             (((ev.message >> 24) & 0xff) == switchEvt)) {
  358.         in_background = ((ev.message & 0x1) == 0);
  359.         /* PWP: do stuff for disabling the status window here */
  360.         }
  361.         updateCursor(ttermw, 1, ev.message);
  362.         break;
  363.     }
  364.  
  365.     /*
  366.      * now try handing any remaining events to the dialog manager
  367.      */
  368.     if (IsDialogEvent (&ev)) {    /* meant for dialog manager? */
  369.     
  370.         /* must be for screen */
  371.         if (DialogSelect (&ev, &mydlg, &item))
  372.         scrmydlg (item);    /* let him handle it */
  373.  
  374.     } else switch (ev.what) {    /* we may need to do something */
  375.       /*
  376.        * Dialog manager didn't want it -- deal with remainders.
  377.        */
  378.       case updateEvt:
  379.         doupdate ((WindowPtr) ev.message);    /* handle updates */
  380.         break;
  381.  
  382.       case mouseDown:    /* Mouse event */
  383.         domouse (&ev, TRUE);
  384.         break;
  385.     }
  386.     } while (deplete);        /* return now, or loop */
  387. }                /* miniparser */
  388.  
  389.  
  390. #ifdef notdef
  391. /*
  392.  * Handle events for getchar(), etc.
  393.  */
  394. char microparser (deplete, menuok, time)
  395.     int deplete;            /* deplete pending events */
  396.     int menuok;                /* true if menus ok */
  397.     long time;                /* max delay in seconds */
  398. {
  399.     int sconnected;
  400.     char menu_event();
  401.     char nextcmd ();
  402.     char rstate = 0;
  403.     long limitticks;
  404.     EventRecord ev;
  405.     DialogPtr mydlg;
  406.     short item;
  407.     struct cmdw *cmdw;
  408.     
  409.     limitticks = TickCount() + 60L * time; /* set max time */
  410.  
  411.     /*
  412.      * Save state of connected.  If it changes, exit macparser().
  413.      */
  414.     sconnected = connected;
  415.  
  416.     /*
  417.      * Update the command window.
  418.      */
  419.     updatecommand(ctermw);
  420.     updatecommand(ttermw);
  421.  
  422.     do {
  423.     if (sconnected != connected)
  424.         return (rstate);
  425.  
  426.     if (have_multifinder) {
  427.         /* task, task */
  428.         /*
  429.          * NOTE: mf_sleep_time MUST be < 50 to work right, due to
  430.          * a bug in MultiFinder 1.0.  See TN 177.
  431.          */
  432.         if (mf_sleep_time > 30L)
  433.             mf_sleep_time = 30L;
  434.         WaitNextEvent (everyEvent, &ev, mf_sleep_time, NULL);
  435.     } else {
  436.         SystemTask ();        /* let the system move */
  437.         GetNextEvent (everyEvent, &ev); /* get an event */
  438.     }
  439.  
  440.     /* See if time has expired */
  441.     if (time && (TickCount() > limitticks))
  442.         return '\0';
  443.  
  444.     /* Handle all the pending port chars */
  445.     inpchars(ttermw);
  446.  
  447.     /*
  448.      * Be paranoid: check for all the events that IsDialogEvent might trap
  449.      * but we want to do something with anyway FIRST.
  450.      */
  451.     switch (ev.what) {        /* we may need to do something */
  452.     case keyDown:
  453.         if ((ev.modifiers & cmdKey) && ((ev.message & 0x7f) == '.')) {
  454.         if (CautionAlert (ALERT_ABORT, 
  455.                   (ModalFilterProcPtr) NILPROC) == OKBtn)
  456.             return('a');    /* move into abort state */
  457.         } else if ((ev.modifiers & cmdKey) && (mcmdactive)) {
  458.         if (menuok)
  459.             rstate = menu_event(MenuKey(ev.message&charCodeMask));
  460.         if (rstate)
  461.             return rstate;
  462.         if (quit)
  463.             doexit(GOOD_EXIT,-1);
  464.         } else if (FrontWindow() == ttermw->window) {
  465.         if (!connected) {
  466.             if (console_char(ctermw, &ev)) {
  467.             updateCursor(ctermw, 1, NIL); /* set the watch */
  468.             return (rstate); /* and return with state */
  469.             }
  470.         } else {
  471.             handle_char (ttermw, &ev);
  472.             if (sconnected != connected)
  473.             return (rstate);
  474.         }
  475.         } else if (cmdw = cmdwbywindow(FrontWindow())) {
  476.         rcdkey (cmdw, &ev);
  477.         } else if (FrontWindow () == ctermw->window) {
  478.         /* always a command in this window */
  479.         if (console_char(ctermw, &ev)) {
  480.             cursor_erase(ctermw);
  481.             updateCursor(ctermw, 1, NIL); /* set the watch */
  482.             return (rstate); /* and return with state */
  483.         }
  484.         }
  485.         break;
  486.  
  487.     case app4Evt:            /* really a suspend/resume event */
  488.         if ((have_multifinder) &&
  489.             (((ev.message >> 24) & 0xff) == switchEvt)) {
  490.         in_background = ((ev.message & 0x1) == 0);
  491.         /* PWP: do stuff for disabling the status window here */
  492.         }
  493.         updateCursor(ctermw, 1, ev.message);
  494.         break;
  495.     } /* switch */
  496.     
  497.     /*
  498.      * now try handing any remaining events to the dialog manager
  499.      */
  500.     if (IsDialogEvent (&ev)) {    /* meant for dialog manager? */
  501.     
  502.         /* must be for screen */
  503.         if (DialogSelect (&ev, &mydlg, &item))
  504.         scrmydlg (item);    /* let him handle it */
  505.  
  506.     } else switch (ev.what) {    /* we may need to do something */
  507.         /*
  508.          * Dialog manager didn't want it -- deal with remainders.
  509.          */
  510.     case updateEvt:
  511.         doupdate ((WindowPtr) ev.message); /* handle updates */
  512.         break;
  513.  
  514.     case mouseDown:            /* Mouse event */
  515.         rstate = domouse (&ev, FALSE);
  516.         break;
  517.  
  518.     case activateEvt:        /* (de)active a window */
  519.         doactivate ((WindowPtr) ev.message, ev.modifiers);
  520.         break;
  521.     } /* switch */
  522.     } while (deplete);            /* return now, or loop */
  523.  
  524.     return rstate;
  525. }                    /* miniparser */
  526. #endif
  527.  
  528. /*
  529.  * Handle events.
  530.  */
  531. char newparser (deplete, menuok, time)
  532.     int deplete;            /* deplete pending events */
  533.     int menuok;                /* true if menus ok */
  534.     long time;                /* max delay in seconds */
  535. {
  536.     int sconnected;
  537.     char menu_event();
  538.     char nextcmd ();
  539.     char rstate = 0;
  540.     long limitticks;
  541.     EventRecord ev;
  542.     DialogPtr mydlg;
  543.     WindowPtr w;
  544.     short item;
  545.     struct cmdw *cmdw;
  546.     
  547.     limitticks = TickCount() + 60L * time; /* set max time */
  548.  
  549.     /*
  550.      * Save state of connected.  If it changes, exit the parser.
  551.      */
  552.     sconnected = connected;
  553.  
  554.     /*
  555.      * Update the vt100 windows.
  556.      */
  557.     updatecommand(ctermw);
  558.     updatecommand(ttermw);
  559.  
  560.     protocmd = 0;            /* not in protocol mode */
  561.     do {
  562.     /*
  563.      * Update the cursor.
  564.      */
  565.     w = FrontWindow();
  566.     if (w == ttermw->window)
  567.         updateCursor(ttermw, 0, w);
  568.     else if (w == ctermw->window)
  569.         updateCursor(ctermw, 0, w);
  570.     else if (cmdw = cmdwbywindow(w))
  571.         cmdwUpdateCursor(cmdw);
  572.  
  573. #ifdef notdef /* ??? */
  574.     else updateCursor(ttermw, 0, w);
  575. #endif
  576.  
  577.     if (sconnected != connected)
  578.         return (rstate);
  579.  
  580.     if (have_multifinder) {
  581.         /* task, task */
  582.         /*
  583.          * NOTE: mf_sleep_time MUST be < 50 to work right, due to
  584.          * a bug in MultiFinder 1.0.  See TN 177.
  585.          */
  586.         if (mf_sleep_time > 30L)
  587.             mf_sleep_time = 30L;
  588.         WaitNextEvent (everyEvent, &ev, mf_sleep_time, NULL);
  589.     } else {
  590.         SystemTask ();        /* let the system move */
  591.         GetNextEvent (everyEvent, &ev); /* get an event */
  592.     }
  593.  
  594.     /* 
  595.      * See if time has expired 
  596.      */
  597.     if (time && (TickCount() > limitticks))
  598.         return '\0';
  599.     if (alarmtime && alarmfunc && (((ulong)TickCount() - alarmtime) > 0))
  600.         (*alarmfunc)(0);
  601.  
  602.     /* Handle all the pending port chars */
  603.     inpchars(ttermw);
  604.  
  605.     /*
  606.      * Be paranoid: check for all the events that IsDialogEvent might trap
  607.      * but we want to do something with anyway FIRST.
  608.      */
  609.     switch (ev.what) {        /* we may need to do something */
  610.     case keyDown:
  611.     case autoKey:
  612.         if ((ev.modifiers & cmdKey) && ((ev.message & 0x7f) == '.')) {
  613.         if (CautionAlert (ALERT_ABORT, 
  614.                   (ModalFilterProcPtr) NILPROC) == OKBtn)
  615.             return('a');    /* move into abort state */
  616.         } else if ((ev.modifiers & cmdKey) && (mcmdactive)) {
  617.         if (menuok)
  618.             rstate = menu_event(MenuKey(ev.message&charCodeMask));
  619.         if (rstate)
  620.             return rstate;
  621.         } else if (FrontWindow() == ttermw->window) {
  622.         if (!connected) {
  623.             if (console_char(ctermw, &ev)) {
  624.             updateCursor(ctermw, 1, NIL); /* set the watch */
  625.             return (rstate); /* and return with state */
  626.             }
  627.         } else {
  628.             handle_char (ttermw, &ev);
  629.             if (sconnected != connected)
  630.             return (rstate);
  631.         }
  632.         } else if (cmdw = cmdwbywindow(FrontWindow())) {
  633.         rcdkey (cmdw, &ev);
  634.         } else if (FrontWindow () == ctermw->window) {
  635.         /* always a command in this window */
  636.         if (console_char(ctermw, &ev)) {
  637.             cursor_erase(ctermw);
  638.             updateCursor(ctermw, 1, NIL); /* set the watch */
  639.             return (rstate); /* and return with state */
  640.         }
  641.         }
  642.         break;
  643.  
  644.     case app4Evt:            /* really a suspend/resume event */
  645.         if (!have_multifinder) {
  646.         updateCursor(ctermw, 1, ev.message);
  647.         break;
  648.         }
  649.  
  650.         switch ((ev.message>>24) & 0xff) {
  651.         case switchEvt:
  652.         /* Treat switch events as activate events too */
  653.         if (ev.message & 0x01) { /* Resume Event */
  654.             in_background = FALSE;
  655.             doactivate(FrontWindow(), activeFlag);
  656.         } else {        /* Suspend Event */
  657.             in_background = TRUE;
  658.             doactivate(FrontWindow(), 0);
  659.             /* PWP: do stuff for disabling the status window here */
  660.         }
  661.         }
  662.         updateCursor(ctermw, 1, ev.message);
  663.         break;
  664.     } /* switch */
  665.     
  666.     /*
  667.      * Dialog manager didn't want it -- deal with remainders.
  668.      */
  669.     switch (ev.what) {
  670.     case updateEvt:
  671.         doupdate ((WindowPtr) ev.message); /* handle updates */
  672.         break;
  673.  
  674.     case mouseDown:            /* Mouse event */
  675.         if (rstate = domouse (&ev, FALSE))
  676.         return(rstate);
  677.         break;
  678.  
  679.     case activateEvt:        /* (de)active a window */
  680.         doactivate ((WindowPtr) ev.message, ev.modifiers);
  681.         break;
  682.  
  683.     case diskEvt:            /* disk inserted */
  684.         if (((ev.message >> 16) & 0xFFFF) != noErr) {
  685.         DILoad();
  686.         DIBadMount(ev.where, ev.message);
  687.         DIUnload();
  688.         }
  689.         break;
  690.  
  691.     } /* switch */
  692.  
  693.     /*
  694.      * now try handing any remaining events to the dialog manager
  695.      */
  696.     if (IsDialogEvent (&ev)) {
  697.         if (DialogSelect (&ev, &mydlg, &item))
  698.         scrmydlg (item);    /* let him handle it */
  699.         continue;
  700.     } 
  701.  
  702.     /*
  703.      * Flash the cursors.
  704.      */
  705.     if ((FrontWindow() == ttermw->window) && (ttermw->blinkcursor))
  706.         flash_cursor(ttermw);
  707.     else if ((FrontWindow() == ctermw->window) && (ctermw->blinkcursor))
  708.         flash_cursor(ctermw);
  709.     else if (activecmdw)
  710.         TEIdle(activecmdw->teh);
  711.  
  712.     } while (deplete);            /* return now, or loop */
  713.  
  714.     return rstate;
  715. }
  716.  
  717.  
  718. /****************************************************************************/
  719. /* domouse  - handle mouse down events for different windows. */
  720. /****************************************************************************/
  721. char
  722. domouse (evt, mini)
  723. EventRecord *evt;
  724.     int mini;                /* TRUE if miniparser */
  725. {
  726.     char state = 0;
  727.     WindowPtr window;
  728.     int evtwcode;
  729.     struct cmdw *cmdw;
  730.  
  731.     evtwcode = FindWindow (evt->where, &window);
  732.  
  733.     switch (evtwcode) {        /* Tell us where */
  734.       case inMenuBar:        /* Looking at the menus? */
  735.     if (mini)
  736.         break;
  737.     updateCursor(ttermw, 1, (WindowPtr) NIL); /* (UoR) mouse cursor off */
  738.     state = menu_event (MenuSelect (evt->where));
  739.     break;            /* All done */
  740.  
  741.       case inSysWindow:    /* Looking at system, like */
  742.     SystemClick (evt, window);    /* a desk accessary */
  743.     break;            /* Let the system handle it */
  744.  
  745.       case inContent:
  746.     if (window != FrontWindow ()) {
  747.         if (cmdw = cmdwbywindow(window))
  748.         cmdwSelectWindow(cmdw);
  749.         else
  750.         kSelectWindow (window);    /* make window current */
  751.     } else if (window == ttermw->window)
  752.         termmouse (ttermw, evt);
  753.     else if (cmdw = cmdwbywindow(window))
  754.         rcdmouse (cmdw, evt);
  755.     else if (window == ctermw->window)
  756.         termmouse(ctermw, evt);
  757.     break;
  758.  
  759.       case inDrag:        /* Wanna drag? */
  760.     kSelectWindow(window);
  761.     DragWindow (window, evt->where, &qd.screenBits.bounds);
  762.     break;
  763.  
  764.       case inGoAway:
  765.     if (cmdw = cmdwbywindow(window)) {
  766.         if (TrackGoAway (cmdw->window, evt->where)) {
  767.         closecmdw(cmdw);
  768.         /* !!!!!!!!!! if was a file window, destroy it */
  769.         }
  770.     } else if (window == ctermw->window) {
  771.         if (TrackGoAway (ctermw->window, evt->where))
  772.         closetermw(ctermw);
  773.     } else if (window == ttermw->window) {
  774.         if (TrackGoAway (ttermw->window, evt->where))
  775.         closetermw(ttermw);
  776.     }
  777.     break;
  778.  
  779.       case inGrow:
  780.     if (window != FrontWindow ()) {
  781.         if (cmdw = cmdwbywindow(window))
  782.         cmdwSelectWindow(cmdw);
  783.         else
  784.         kSelectWindow (window);    /* make window current */
  785.     } else if (window == ttermw->window)
  786.         growterm(ttermw, &evt->where);
  787.     else if (cmdw = cmdwbywindow(window))
  788.         growremwindow(cmdw, evt->where);
  789.     else if (window == ctermw->window)
  790.         growterm(ctermw, &evt->where);
  791.     break;
  792.     }
  793.     
  794.     ttermw->last_flash = TickCount ();    /* reset timer for flashes */
  795.     return (state);            /* return with new state or 0 */
  796. }                /* domouse */
  797.  
  798.  
  799.  
  800. /****************************************************************************/
  801. /* doupdate - handle update event on different windows, dispatch to */
  802. /*              redraw routines */
  803. /****************************************************************************/
  804. doupdate (window)
  805. WindowPtr window;
  806. {
  807.     GrafPtr savePort;
  808.     struct cmdw *cmdw;
  809.  
  810.     GetPort (&savePort);
  811.     SetPort (window);
  812.     BeginUpdate (window);
  813.  
  814.     if (window == ttermw->window) {
  815.     term_redraw(ttermw);        /* terminal window */
  816.     } else if (cmdw = cmdwbywindow(window)) {
  817.     rcdupdate (cmdw);        /* Redraw  window */
  818.     } else if (window == ctermw->window) {
  819.     term_redraw(ctermw);
  820.     }
  821.  
  822.     EndUpdate (window);
  823.     SetPort (savePort);
  824. }                /* doupdate */
  825.  
  826.  
  827.  
  828. #define NNN 20                /* for debugging */
  829. static WindowPtr wqueue[NNN];
  830. static int mqueue[NNN];
  831. static int qindex = 0;
  832.  
  833. /****************************************************************************/
  834. /* doactivate - activate a window */
  835. /****************************************************************************/
  836. doactivate (window, mod)
  837. WindowPtr window;
  838. int mod;
  839. {
  840.     GrafPtr savePort;
  841.     struct cmdw *cmdw;
  842.  
  843.     GetPort (&savePort);
  844.     SetPort (window);
  845.  
  846.     /*
  847.      * save last action in circular queue for debugging
  848.      */
  849.     wqueue[qindex] = window;
  850.     mqueue[qindex] = mod;
  851.     if (++qindex == NNN)
  852.     qindex = 0;
  853.  
  854.     HiliteWindow (window, ((mod & activeFlag) != 0));
  855.     if (!(mod & activeFlag))
  856.     activecmdw = NULL;
  857.     if (cmdw = cmdwbywindow(window))
  858.     rcdactivate (cmdw, mod);
  859.     else if (window == ctermw->window) {
  860.     term_activate(ctermw, mod);
  861.     updateCursor(ctermw, 1, ctermw->window); /* ???? was ttermw */
  862.     } else if (window == ttermw->window) {
  863.         term_activate(ttermw, mod);
  864.     updateCursor(ttermw, 1, ttermw->window);
  865.     }
  866.  
  867. #ifdef COMMENT
  868.     if (!EmptyRgn(((WindowPeek)terminalWindow)->updateRgn))
  869.     doupdate (terminalWindow);    /* Fake an update event */
  870. #endif
  871.  
  872.     SetPort (savePort);
  873. }                    /* doactivate */
  874.  
  875. show_queue ()
  876. {
  877.     int i;
  878.  
  879.     i = qindex + 1;
  880.     while (i != qindex) {
  881.     if (i >= NNN)
  882.         i = 0;
  883.     printf("%3d: window=0x%x mod=0x%x\n", i, wqueue[i], mqueue[i]);
  884.     
  885.     i++;
  886.     }
  887. }
  888.  
  889. char genstr[100];
  890.  
  891. /****************************************************************************/
  892. /****************************************************************************/
  893. char menu_event (menu_item)
  894.     long menu_item;
  895. {
  896.     int r;
  897.     Boolean saveas = FALSE;
  898.     short menu = HiWord (menu_item);    /* decompose arg */
  899.     short item = LoWord (menu_item);
  900.     char state = '\0';
  901.     int remotedialog ();    /* returns boolean */
  902.     WindowPtr window;
  903.     struct cmdw *cmdw;
  904.     struct termw *termw;
  905.     char scratch[255];
  906.  
  907.     switch (menu) {
  908.       case APPL_MENU:        /* Mac system menu item */
  909.     handapple (item);
  910.     break;            /* all done */
  911.  
  912.       case FILE_MENU:
  913.       case FILE_MEN2:
  914.     switch (item) {        /* Find out which was selected */
  915.       case QUIT_FIL:    /* Want to quit program? */
  916.         doexit(GOOD_EXIT,-1);
  917.         /* should never return */
  918.  
  919.       case XFER_FIL:
  920.         handlelaunch ();    /* Handle x-fer to application */
  921.         break;
  922.  
  923.       case SAVE_FIL:    /* save settings */
  924.         savevals();
  925.         break;
  926.  
  927.       case LOAD_FIL:    /* load settings */
  928.         loadvals ();
  929.         HiliteMenu (0);    /* Done doing menu, so un-hilite */
  930.         return 'n';        /* null command to force parser return */
  931.  
  932.       case PRINT_FIL:    /* Print... */
  933.         doprinter(FrontWindow());
  934.         break;
  935.  
  936.       case PBUF_FIL:    /* Print the Buffer */
  937.         now_print();
  938.         break;
  939.         
  940.       case PSTAT_FIL:    /* Print Buffer Status Dialog Box */
  941.         pr_stat();
  942.         break;
  943.         
  944.       case PDISC_FIL:    /* Discard the Print Buffer */
  945.         if (hPrintBuffer)
  946.         DisposHandle(hPrintBuffer);
  947.         hPrintBuffer = 0L;
  948.         lPrintBufferChars = 0L;
  949.         updatepstat();
  950.         break;
  951.  
  952.       case POPEN_FIL:       /* Open Captured Text */
  953.         if (hPrintBuffer && lPrintBufferChars) {
  954.         newfile(hPrintBuffer);
  955.         lPrintBufferChars = lPrintBufferAt = 0L; /* flush buffer */
  956.         updatepstat();
  957.         } else
  958.         SysBeep(3);
  959.         break;
  960.  
  961.       case TAKE_FIL:    /* Take Command File... */
  962.         takedialog();
  963.         HiliteMenu (0);    /* Done doing menu, so un-hilite */
  964.         return 'n';        /* null command to force parser return */
  965.  
  966.       case TAKEW_FIL:    /* Take Command from Window */
  967.         if ((cmdw = cmdwbywindow(FrontWindow())) == NULL) {
  968.         SysBeep(3);
  969.         break;
  970.         }
  971.         if ((cmdw->flags & CMDWF_FOPEN) || (!(cmdw->flags & CMDWF_FILE))) {
  972.         SysBeep(3);
  973.         break;
  974.         }
  975.         sprintf(scratch, "%%%%%%%d", cmdw->id);
  976.         kShowWindow(ctermw);    /* force command window */
  977.         kSelectWindow(ctermw->window);
  978.         getlfile(scratch, 0);    /* queue the take file */
  979.         HiliteMenu (0);        /* Done doing menu, so un-hilite */
  980.         return 'n';              /* null command to force parser return */
  981.  
  982.       case NEW_FIL:
  983.         newfile(0L);
  984.         break;
  985.  
  986.       case OPEN_FIL:
  987.         openfile();
  988.         break;
  989.  
  990.       case CLOSE_FIL:
  991.         if (cmdw = cmdwbywindow(FrontWindow())) {
  992.         closecmdw(cmdw);
  993.             /* !!!!! Need to destroy window, unlink and free cmdw, etc */
  994.         } else if (termw = termwbywindow(FrontWindow()))
  995.         closetermw(termw);
  996.         break;
  997.         
  998.       case SAVEAS_FIL:
  999.         saveas = TRUE;
  1000.       case SAVEF_FIL:
  1001.         if (cmdw = cmdwbywindow(FrontWindow())) {
  1002.         if (cmdw->flags & CMDWF_FILE) {
  1003.             savefile(cmdw, saveas);
  1004.             break;
  1005.         }
  1006.         }
  1007.         SysBeep(1);
  1008.         break;
  1009.     }
  1010.     break;
  1011.  
  1012.       case EDIT_MENU:        /* PWP: good for DA editors */
  1013.       case EDIT_MEN2:        /* PWP: good for DA editors */
  1014.         window = FrontWindow();    /* we do different things based on this */
  1015.     
  1016.         switch(item) {
  1017.       case UNDO_EDIT:    /* undo */
  1018.         if (window == ttermw->window) {
  1019.         SysBeep(3);
  1020.         } else if (cmdw = cmdwbywindow(window)) {
  1021.         SysBeep (3);
  1022.         } else if (window == ctermw->window) {
  1023.         SysBeep (3);
  1024.         } else {
  1025.         if (!SystemEdit (item - 1))
  1026.             SysBeep (3);
  1027.         }
  1028.         break;
  1029.  
  1030.       case CUT_EDIT:    /* cut */
  1031.         if (window == ttermw->window) {
  1032.         scr_copy(ttermw);
  1033.         } else if (cmdw = cmdwbywindow(window)) {
  1034.         rcd_cut(cmdw);
  1035.         cmdw->flags |= CMDWF_MODIFIED;
  1036.         } else if (window == ctermw->window) {
  1037.         scr_copy(ctermw);
  1038.         } else {
  1039.         if (!SystemEdit (item - 1))
  1040.             SysBeep (3);
  1041.         }
  1042.         break;
  1043.  
  1044.       case COPY_EDIT:    /* copy */
  1045.         if (window == ttermw->window) {
  1046.         scr_copy(ttermw);
  1047.         } else if (cmdw = cmdwbywindow(window)) {
  1048.         rcd_copy(cmdw);
  1049.         } else if (window == ctermw->window) {
  1050.         scr_copy(ctermw);
  1051.         } else {
  1052.         if (!SystemEdit (item - 1))
  1053.             SysBeep (3);
  1054.         }
  1055.         break;
  1056.  
  1057.       case PASTE_EDIT:    /* paste */
  1058.         if (window == ttermw->window) {
  1059.         scr_paste(ttermw);
  1060.         } else if (cmdw = cmdwbywindow(window)) {
  1061.         rcd_paste(cmdw);
  1062.         cmdw->flags |= CMDWF_MODIFIED;
  1063.         } else if (window == ctermw->window) {
  1064.         cmd_paste(ttermw);
  1065.         state = 'p';        /* wake up getchar() */
  1066.         } else {
  1067.         if (!SystemEdit (item - 1))
  1068.             SysBeep (3);
  1069.         }
  1070.         break;
  1071.  
  1072.       case CLEAR_EDIT:    /* clear */
  1073.         if (window == ttermw->window) {
  1074.         SysBeep(3);
  1075.         } else if (cmdw = cmdwbywindow(window)) {
  1076.         rcd_clear(cmdw);
  1077.         cmdw->flags |= CMDWF_MODIFIED;
  1078.         } else if (window == ctermw->window) {
  1079.         SysBeep(3);
  1080.         } else {
  1081.         if (!SystemEdit (item - 1))
  1082.             SysBeep (3);
  1083.         }
  1084.         break;
  1085.       
  1086.     }
  1087.     break;
  1088.  
  1089.       case SETG_MENU:
  1090.       case SETG_MEN2:
  1091.     switch (item) {
  1092.       case PROT_SETG:
  1093.         protodialog ();
  1094.         break;
  1095.  
  1096.       case COMM_SETG:
  1097.         commdialog ();    /* communications dialog */
  1098.         break;
  1099.  
  1100.       case FILE_SETG:
  1101.         setfiledialog ();    /* do default file settings */
  1102.         break;
  1103.  
  1104.       case TERM_SETG:    /* do terminal emulation settings */
  1105.         termsetdialog (ttermw);
  1106.         break;
  1107.  
  1108.       case CHARS_SETG:    /* do terminal emulation settings */
  1109.         charsetdialog (ttermw);
  1110.         break;
  1111.  
  1112.       case SCRD_SETG:    /* fkeys  active / not active */
  1113.         CheckItem (menus[SETG_MENU], SCRD_SETG,
  1114.                (fkeysactive = !fkeysactive));
  1115.         enable_fkeys (fkeysactive);
  1116.         break;
  1117.  
  1118.       case MCDM_SETG:    /* menu command keys active / not active */
  1119.         CheckItem (menus[SETG_MENU], MCDM_SETG,
  1120.                (mcmdactive = !mcmdactive));
  1121.         setup_menus();    /* redo menus */
  1122.         break;
  1123.  
  1124.       case KEYM_SETG:
  1125.         keymacros ();
  1126.         break;
  1127.  
  1128.       case MODF_SETG:
  1129.         keymoddialog ();
  1130.         break;
  1131.     }
  1132.     break;
  1133.  
  1134.     /*
  1135.      * return either 'g' for generic or 'c' for host with cmarg holding
  1136.      * cmd
  1137.      */
  1138.  
  1139.       case REMO_MENU:
  1140.       case REMO_MEN2:
  1141.     cmarg = genstr;            /* indicate cmd ok to proceed */
  1142.     switch (item) {
  1143.       case SEND_REMO:        /* send a file: local, remote files */
  1144.         if (!dosenddialog (&cmarg, &cmarg2))
  1145.         break;
  1146.         r = zxpand(cmarg);    /* must call this now since sinit() doesn't */
  1147.         if (r <= 0)
  1148.             printerr("zxpand returned ", r);
  1149.         nfils = -1;            /* Use cmarg, not cmlist */
  1150.         state = 's';        /* return with send state */
  1151.         protocmd = item;
  1152.         scrcreate ();        /* create the status screen */
  1153.         break;
  1154.  
  1155.       case RECV_REMO:        /* Ask for recv info -- */
  1156.         initfilrecv ();        /* init recv flags */
  1157.         state = 'v';        /* return with recv state */
  1158.         protocmd = item;
  1159.         scrcreate ();        /* create the status screen */
  1160.         break;
  1161.  
  1162.       case GETS_REMO:        /* Get from server */
  1163.         if (dogetfdialog (&cmarg)) {
  1164.         state = 'r';        /* Say we want to get */
  1165.         protocmd = item;
  1166.         scrcreate ();        /* create the status screen */
  1167.         }
  1168.         break;
  1169.         
  1170.       case STATS_REMO:        /* show transfer stats */
  1171.         show_stats();
  1172.         cmarg = NILPTR;
  1173.         break;
  1174.         
  1175.       case LCD_REMO:        /* set transfer directory */
  1176.         set_cwd();
  1177.         cmarg = NILPTR;
  1178.         break;
  1179.  
  1180.       case FIN_REMO:
  1181.         state = 'g';
  1182.         protocmd = -1;        /* hey we're going to protocol! */
  1183.         ssetgen (genstr, 'F', "", "", "");    /* Finish */
  1184.         break;
  1185.  
  1186.       case BYE_REMO:
  1187.         state = 'g';
  1188.         protocmd = -1;        /* hey we're going to protocol! */
  1189.         ssetgen (genstr, 'L', "", "", "");    /* Bye, logout */
  1190.         break;
  1191.  
  1192.       case SERV_REMO:
  1193.         displa = 1;
  1194.         scrcreate ();        /* create the status screen */
  1195.         protocmd = item;
  1196.         return ('x');
  1197.  
  1198.       default:
  1199.         if (!remotedialog (item, genstr))
  1200.         cmarg = NILPTR;        /* cancel issued, prevent it */
  1201.         else {
  1202.         protocmd = -1;        /* hey we're going to protocol! */
  1203.         if (item == HOST_REMO)
  1204.             state = 'c';
  1205.         else
  1206.             state = 'g';
  1207.         }
  1208.         break;
  1209.     } /* switch item */
  1210.     if (protocmd) {
  1211.         lastCursor=0L;
  1212.         SetCursor(watchcurs);
  1213.     }
  1214.     break;
  1215.     
  1216.       case WIND_MENU:
  1217.       case WIND_MENU2:
  1218.     cmarg = genstr;            /* indicate cmd ok to proceed */
  1219.     switch (item) {
  1220.       case TERM_WIND:        /* Show terminal window */
  1221.         kShowWindow(ttermw);
  1222.         kSelectWindow(ttermw->window); /* make window current */
  1223.         cmarg = NILPTR;        /* Don't do anything else */
  1224.         break;
  1225.  
  1226.       case CMDW_WIND:        /* Show command window */
  1227.         kShowWindow(ctermw);
  1228.         kSelectWindow(ctermw->window);
  1229.         cmarg = NILPTR;        /* Don't do anything else */
  1230.         break;
  1231.  
  1232.       case RESP_WIND:
  1233.         rcmdwshow(rcmdw);
  1234.         cmarg = NILPTR;        /* Don't do anything else */
  1235.         break;
  1236.  
  1237.       default:
  1238.         for (cmdw = cmdwl; cmdw; cmdw = cmdw->next) {
  1239.         if (item == cmdw->menuitem) {
  1240.             cmdwSelectWindow(cmdw);
  1241.             break;
  1242.         }
  1243.         }
  1244.         break;
  1245.     }
  1246.     break;
  1247.     
  1248.       case LOG_MENU:
  1249.       case LOG_MEN2:
  1250.     switch(item) {
  1251.       case SLOG_LOG:        /* session logging */
  1252.         if (seslog) {
  1253.             scrlasttolog(ttermw);    /* save the last line on the screen */
  1254.         closeslog ();
  1255.         seslog = 0;
  1256.         } else {
  1257.         seslog = openslog ();
  1258.         scrtolog(ttermw);   /* if the file is open, just do the dump */
  1259.         }
  1260.         CheckItem (menus[LOG_MENU], SLOG_LOG, seslog);
  1261.         if (seslog) {
  1262.             EnableItem(menus[LOG_MENU], SDMP_LOG);
  1263.         } else {
  1264.             DisableItem(menus[LOG_MENU], SDMP_LOG);
  1265.         }
  1266.         break;
  1267.  
  1268.       case SDMP_LOG:        /* dump screen to session log */
  1269.         if (seslog)    {        /* session logging active? */
  1270.         scrtolog(ttermw);   /* if the file is open, just do the dump */
  1271.         } else {
  1272.         SysBeep(3);    /* can't dump screen without a log file. */
  1273.             DisableItem(menus[LOG_MENU], SDMP_LOG);
  1274.         }
  1275.         break;
  1276.  
  1277.       case TLOG_LOG:        /* transaction logging */
  1278.         if (tralog) {
  1279.         closetlog ();
  1280.         tralog = 0;
  1281.         } else {
  1282.         tralog = opentlog ();
  1283.         }
  1284.         CheckItem (menus[LOG_MENU], TLOG_LOG, tralog);
  1285.         break;
  1286.  
  1287.       case PLOG_LOG:        /* packet logging */
  1288.         if (pktlog) {
  1289.         closetlog ();
  1290.         pktlog = 0;
  1291.         } else {
  1292.         pktlog = openplog ();
  1293.         }
  1294.         CheckItem (menus[LOG_MENU], PLOG_LOG, pktlog);
  1295.         break;
  1296.  
  1297.       case DLOG_LOG:        /* log debugging */
  1298.         if (deblog) {
  1299.         (void) closedlog ();
  1300.         deblog = 0;
  1301.         } else {
  1302.         deblog = opendlog ();
  1303.         rcmdwshow (rcmdw);    /* display the remote cmd window */
  1304.         /* Debugger(); */
  1305.         }
  1306.         CheckItem (menus[LOG_MENU], DLOG_LOG, deblog);
  1307.         break;
  1308.  
  1309.       case DBGR_LOG:        /* call debugger */
  1310.         Debugger();
  1311.         break;
  1312.  
  1313.     }
  1314.     break;
  1315.  
  1316.     case FONT_MENU:
  1317.     if (item <= BIGSZ_FONT) {    /* handle a font size request */
  1318.         change_current_size (ttermw, item);
  1319.     } else {        /* handle a font request */
  1320.         change_current_font(ttermw,item);
  1321.     }
  1322.     setup_font_menu();    /* update font and sizes */
  1323.     break;
  1324.  
  1325.     case SPCL_MENU:            /* Special */
  1326.     case SPCL_MENU2:
  1327.         window = FrontWindow();    /* we do different things based on this */
  1328.     switch (item) {
  1329.       case BREAK_SPCL:        /* send break */
  1330.         if (window == ttermw->window)
  1331.         sendbreak(5);
  1332.         else
  1333.         SysBeep(3);
  1334.         break;
  1335.  
  1336.       case LBREAK_SPCL:        /* send break */
  1337.         if (window == ttermw->window)
  1338.         sendbreak(70);
  1339.         else
  1340.         SysBeep(3);
  1341.         break;
  1342.  
  1343.       case XON_SPCL:        /* send XON */
  1344.         if (window == ttermw->window)
  1345.         do_xon();
  1346.         else
  1347.         SysBeep(3);
  1348.         break;
  1349.  
  1350.       case DTR_SPCL:        /* toggle DTR */
  1351.         if (window == ttermw->window)
  1352.         toggle_dtr(70);
  1353.         else
  1354.         SysBeep(3);
  1355.         break;
  1356.  
  1357.       case RESET_SPCL:    /* Reset terminal */
  1358.         if (window == ttermw->window)
  1359.         term_reset(ttermw);    /* reset the terminal emulator */
  1360.         else
  1361.         SysBeep(3);
  1362.         break;
  1363.     }
  1364.     break;
  1365.     }
  1366.  
  1367.     HiliteMenu (0);            /* Done doing menu, so un-hilite */
  1368.  
  1369.     return (state);            /* Don't go into Kermit protocol */
  1370. }                /* menu_event */
  1371.  
  1372. /****************************************************************************/
  1373. /* herald() prints out the version number (but we arn't on a TTY, so don't) */
  1374. /****************************************************************************/
  1375. VOID herald ()
  1376. {
  1377. }                /* herald */
  1378.  
  1379.  
  1380.  
  1381. /****************************************************************************/
  1382. /****************************************************************************/
  1383. /*
  1384.  * conect
  1385.  * This MAC routine duplicates a routine in ckucon.c
  1386.  */
  1387. conect ()
  1388. {
  1389.     connected = 1;            /* put mac into connected mode */
  1390.     sstate = 'c';
  1391.     if (ttermw->window != FrontWindow()) {
  1392.     kShowWindow(ttermw);
  1393.     kSelectWindow(ttermw->window);
  1394.     }
  1395.     return 0;
  1396. }
  1397.  
  1398.  
  1399. /****************************************************************************/
  1400. /****************************************************************************/
  1401. cmdlin ()
  1402. {
  1403.     return (0);            /* nothing parsed */
  1404. }                /* cmdlin */
  1405.  
  1406.  
  1407.  
  1408. /****************************************************************************/
  1409. /****************************************************************************/
  1410. chkint ()
  1411. {
  1412. }                /* chkint */
  1413.  
  1414. /****************************************************************************/
  1415. #ifdef DEBUG
  1416. /*  D E B U G  --  Enter a record in the debugging log  */
  1417.  
  1418. /*
  1419.  Call with a format, two strings, and a number:
  1420.    f  - Format, a bit string in range 0-7.
  1421.         If bit x is on, then argument number x is printed.
  1422.    s1 - String, argument number 1.  If selected, printed as is.
  1423.    s2 - String, argument number 2.  If selected, printed in brackets.
  1424.    n  - Int, argument 3.  If selected, printed preceded by equals sign.
  1425.  
  1426.    f=0 is special: print s1,s2, and interpret n as a char.
  1427. */
  1428. #define DBUFL 2300
  1429. int
  1430. dodebug(f,s1,s2,n) int f, n; char *s1, *s2; {
  1431.     static char *s = 0;
  1432.     char *sp;
  1433.  
  1434.     /*
  1435.      * Allocate s if not done already
  1436.      */
  1437.     if (!s && !(s = malloc(DBUFL)))
  1438.     macfatal("dodebug: no room for s", 0);
  1439.     sp = s;
  1440.  
  1441.     if (!deblog) return (0);        /* If no debug log, don't */
  1442.     switch (f) {
  1443.         case F000:            /* 0, print both strings, */
  1444.         if (strlen(s1) + strlen(s2) + 5 > DBUFL) { /* and n as a char */
  1445.         sprintf(sp,"DEBUG string too long\n");
  1446.         } else {
  1447.         if (n > 31 && n < 127)
  1448.           sprintf(sp,"%s%s:%c\n",s1,s2,n);
  1449.         else if (n < 32 || n == 127)
  1450.           sprintf(sp,"%s%s:^%c\n",s1,s2,(n+64) & 0x7F);
  1451.         else if (n > 127 && n < 160)
  1452.           sprintf(sp,"%s%s:~^%c\n",s1,s2,(n-64) & 0x7F);
  1453.         else if (n > 159 && n < 256)
  1454.           sprintf(sp,"%s%s:~%c\n",s1,s2,n & 0x7F);
  1455.         else sprintf(sp,"%s%s:%d\n",s1,s2,n);
  1456.         }
  1457.         if (zsout(ZDFILE,s) < 0) deblog = 0;
  1458.         break;
  1459.         case F001:            /* 1, "=n" */
  1460.         sprintf(sp,"=%d\n",n);
  1461.         if (zsout(ZDFILE,s) < 0) deblog = 0;
  1462.         break;
  1463.         case F010:            /* 2, "[s2]" */
  1464.         if (strlen(s2) + 4 > DBUFL)
  1465.           sprintf(sp,"DEBUG string too long\n");
  1466.         else sprintf(sp,"[%s]\n",s2);
  1467.         if (zsout(ZDFILE,"") < 0) deblog = 0;
  1468.         break;
  1469.         case F011:            /* 3, "[s2]=n" */
  1470.         if (strlen(s2) + 15 > DBUFL)
  1471.           sprintf(sp,"DEBUG string too long\n");
  1472.         else sprintf(sp,"[%s]=%d\n",s2,n);
  1473.         if (zsout(ZDFILE,s) < 0) deblog = 0;
  1474.         break;
  1475.         case F100:            /* 4, "s1" */
  1476.         if (zsoutl(ZDFILE,s1) < 0) deblog = 0;
  1477.         break;
  1478.         case F101:            /* 5, "s1=n" */
  1479.         if (strlen(s1) + 15 > DBUFL)
  1480.           sprintf(sp,"DEBUG string too long\n");
  1481.         else sprintf(sp,"%s=%d\n",s1,n);
  1482.         if (zsout(ZDFILE,s) < 0) deblog = 0;
  1483.         break;
  1484.         case F110:            /* 6, "s1[s2]" */
  1485.         if (strlen(s1) + strlen(s2) + 4 > DBUFL)
  1486.           sprintf(sp,"DEBUG string too long\n");
  1487.         else sprintf(sp,"%s[%s]\n",s1,s2);
  1488.         if (zsout(ZDFILE,s) < 0) deblog = 0;
  1489.         break;
  1490.         case F111:            /* 7, "s1[s2]=n" */
  1491.         if (strlen(s1) + strlen(s2) + 15 > DBUFL)
  1492.           sprintf(sp,"DEBUG string too long\n");
  1493.         else sprintf(sp,"%s[%s]=%d\n",s1,s2,n);
  1494.         if (zsout(ZDFILE,s) < 0) deblog = 0;
  1495.         break;
  1496.     default:
  1497.         sprintf(sp,"\n?Invalid format for debug() - %d\n",n);
  1498.         if (zsout(ZDFILE,s) < 0) deblog = 0;
  1499.     }
  1500.     return (0);
  1501. }
  1502. #endif
  1503.  
  1504.  
  1505.  
  1506. /****************************************************************************/
  1507. /* sleep - called during protocol for a dismiss.  Keep machine running */
  1508. /*           with calls to the miniparser during this period. */
  1509. /****************************************************************************/
  1510. sleep (secs)
  1511. {
  1512.     long finalticks;        /* tickscount for exit */
  1513.  
  1514.     finalticks = TickCount () + (60 * secs);    /* TickCount for exit  */
  1515.     while (finalticks > TickCount ()) {    /* keep the machine running by */
  1516.     miniparser (TRUE);    /* deplete the Q */
  1517.     if (sstate == 'a')    /* if in abort state, forget */
  1518.         return;        /* this wait */
  1519.     }
  1520. }                /* sleep */
  1521.  
  1522.  
  1523.  
  1524. /****************************************************************************/
  1525. /****************************************************************************/
  1526. VOID ermsg (msg)            /* Print error message */
  1527. char *msg;
  1528. {
  1529.     screen (SCR_EM, 0, 0l, msg);/* Put the error on the screen */
  1530.     tlog (F110, "Error -", msg, 0l);
  1531. }                /* ermsg */
  1532.  
  1533.  
  1534.  
  1535. /****************************************************************************/
  1536. /****************************************************************************/
  1537. VOID intmsg (n)
  1538. long n;
  1539. {
  1540.     return;
  1541. }                /* intmsg */
  1542.  
  1543.  
  1544. /*
  1545.  * openfile
  1546.  * Open an existing TEXT file.
  1547.  */
  1548. openfile ()
  1549. {
  1550.     SFReply savr;
  1551.     Point where;
  1552.     struct cmdw *cmdw = NULL, *tmp;
  1553.     int err;
  1554.     short refNum;
  1555.     long len;
  1556.     char buf[1024];
  1557.     int eol = 0;
  1558.  
  1559.     SetPt (&where, 75, 115);
  1560.     SFGetFile (where, "\pOpen:", (FileFilterProcPtr) NILPROC,
  1561.                1, &texttype, (DlgHookProcPtr) NILPROC, &savr);
  1562.  
  1563.     if (!savr.good)        /* did they hit cancel? */
  1564.     return;            /* yes, so return now */
  1565.  
  1566.     /*
  1567.      * Loop checking to see if this file is already open.  If it
  1568.      * is, just pop up the window.
  1569.      */
  1570.     for (tmp = cmdwl; tmp; tmp = tmp->next) {
  1571.     if ((tmp->vRefNum == savr.vRefNum) && 
  1572.         (strcmp(p2c_tmp(savr.fName), p2c_tmp2(tmp->fName)) == 0)) {
  1573.         cmdwSelectWindow(tmp);
  1574.         return;
  1575.     }
  1576.     }
  1577.  
  1578.     err = FSOpen(savr.fName, savr.vRefNum, &refNum);
  1579.     if (err != noErr) {
  1580.     printfalert("Could not open %s: %d", p2c_tmp(savr.fName), err);
  1581.     return;
  1582.     }
  1583.  
  1584.     /*
  1585.      * Build the window.
  1586.      */
  1587.     cmdw = initcmdw(RCMDBOXID, RCMDVSCROLL, RCMDHSCROLL);
  1588.     cmdw->refNum = refNum;
  1589.     cmdw->vRefNum = savr.vRefNum;    /* save file stuff */
  1590.     cmdw->fName = malloc_pstring(savr.fName);
  1591.     cmdw->flags |= CMDWF_FILE;
  1592.     setwname(cmdw, savr.fName);
  1593.  
  1594.     /*
  1595.      * Read in the file.
  1596.      */
  1597.     for (;;) {
  1598.     len = sizeof(buf);
  1599.     err = FSRead(refNum, &len, buf);
  1600.     if ((err == eofErr) && (len == 0))
  1601.         break;
  1602.     if ((err != noErr) && (err != eofErr)) {
  1603.         printfalert("Error reading file: %d", err);
  1604.         /* !!!! DESTROY THINGS HERE !!!!!!!!!! */
  1605.         return;
  1606.     }
  1607.     
  1608.     /* !!!!! make sure we don't overflow the TE record ? !!!!!!!!! */
  1609.  
  1610.     insertbuf(buf, len, cmdw->teh, &eol);
  1611.     }
  1612.     TESetSelect(0L, 0L, cmdw->teh);    /* select beginning */
  1613.     setscrollmax(cmdw);            /* set the max */
  1614.     rcmdwshow(cmdw);
  1615. }
  1616.  
  1617.  
  1618. /*
  1619.  * Insert buffer into window, processing characters.
  1620.  */
  1621. insertbuf (char *buf, int len, TEHandle teh, int *eol)
  1622. {
  1623.     int n;
  1624.     char *cp, *cp2;
  1625.     static char cr[1] = 0x0d;
  1626.  
  1627.     cp = cp2 = buf;
  1628.     while (cp < buf+len) {
  1629.     switch (*cp) {
  1630.     case 0x0a:            /* linefeed */
  1631.     case 0x0d:            /* return */
  1632.         if (n = (cp - cp2)) {        /* flush buffer */
  1633.         TEInsert(cp2, n, teh);
  1634.         }
  1635.         cp++;            /* skip char */
  1636.         cp2 = cp;
  1637.         *eol = 1;
  1638.         break;
  1639.  
  1640.     default:
  1641.         if (*eol) {
  1642.             *eol = 0;
  1643.             TEInsert(cr, 1, teh);
  1644.         }
  1645.         cp++;
  1646.         break;
  1647.     }
  1648.     }
  1649.     if (n = (cp - cp2)) {            /* flush end of buffer */
  1650.     TEInsert(cp2, n, teh);
  1651.     }
  1652. }
  1653.  
  1654.  
  1655. /*
  1656.  * newfile
  1657.  * Create a new window either empty or given a handle to text.
  1658.  */
  1659. newfile (Handle h)
  1660. {
  1661.     char scratch[255];
  1662.     struct cmdw *cmdw;
  1663.  
  1664.     cmdw = initcmdw(RCMDBOXID, RCMDVSCROLL, RCMDHSCROLL);
  1665.     cmdw->flags |= CMDWF_FILE;
  1666.     sprintf(scratch, "Untitled-%d", titlen++);
  1667.     c2pstr(scratch);
  1668.     setwname(cmdw, scratch);
  1669.  
  1670.     if (h) {
  1671.     TEInsert((Ptr)*h, lPrintBufferChars, cmdw->teh);
  1672.     TESetSelect(0L, 0L, cmdw->teh);    /* select beginning */
  1673.     setscrollmax(cmdw);        /* set the max */
  1674.     cmdw->flags |= CMDWF_MODIFIED;
  1675.     }
  1676.  
  1677.     rcmdwshow(cmdw);
  1678. }
  1679.  
  1680.  
  1681. /*
  1682.  * closefile
  1683.  * Close a file associated with a cmdw.
  1684.  */
  1685. closefile (struct cmdw *cmdw)
  1686. {
  1687.     int err;
  1688.  
  1689.     if (!(cmdw->flags & CMDWF_FILE))
  1690.     return;
  1691.  
  1692.     if (cmdw->refNum == 0)
  1693.     return;
  1694.  
  1695.     err = FSClose((short) cmdw->refNum);
  1696.     if (err != noErr)
  1697.     printfalert("Error closing: %d", err);
  1698.     cmdw->refNum = 0;
  1699. }
  1700.  
  1701.  
  1702. /*
  1703.  * closecmdw
  1704.  * Close a window associated with a cmdw.
  1705.  */
  1706. void closecmdw (struct cmdw *cmdw)
  1707. {
  1708.     struct cmdw *tmp;
  1709.  
  1710.     if (!checksave(cmdw))
  1711.     return;
  1712.  
  1713.     /*
  1714.      * Delete windows menu item, adjust item numbers for
  1715.      * rest of items in the menu.
  1716.      */
  1717.     if (cmdw->menuitem) {
  1718.     DelMenuItem(menus[WIND_MENU], cmdw->menuitem);
  1719.  
  1720.     for (tmp = cmdwl; tmp; tmp = tmp->next)
  1721.         if (tmp->menuitem > cmdw->menuitem)
  1722.         tmp->menuitem--;
  1723.     }
  1724.     cmdw->menuitem = 0;
  1725.  
  1726.     closefile(cmdw);
  1727.  
  1728.     if (!(cmdw->flags & CMDWF_FILE)) {    /* If not a file window (prob rcmdw) */
  1729.     rcmdwhide(cmdw);
  1730.     return;
  1731.     }
  1732.  
  1733.     /*
  1734.      * Unlink and Destroy the cmdw.
  1735.      */
  1736.     if (cmdwl == cmdw) {
  1737.     cmdwl = cmdw->next;
  1738.     } else {
  1739.     for (tmp = cmdwl; tmp; tmp = tmp->next) {
  1740.         if (tmp->next == cmdw) {
  1741.         tmp->next = cmdw->next;
  1742.         break;
  1743.         }
  1744.     }
  1745.     if (tmp == NULL) {
  1746.         printfalert("closecmdw: cmdw not in list");
  1747.         return;
  1748.     }
  1749.     }
  1750.     if (cmdw == activecmdw)
  1751.     activecmdw = NULL;
  1752.  
  1753.     DisposeWindow(cmdw->window);
  1754.     if (cmdw->fName)
  1755.     free(cmdw->fName);
  1756.     if (cmdw->wname)
  1757.     free(cmdw->wname);
  1758.     free(cmdw);
  1759. }
  1760.  
  1761.  
  1762. /*
  1763.  * savefile
  1764.  * Save a file associated with a cmdw.
  1765.  * If as then force a new file name dialog.
  1766.  */
  1767. savefile (struct cmdw *cmdw, Boolean as)
  1768. {
  1769.     int err;
  1770.     long len;
  1771.     short refNum;
  1772.     Point where;
  1773.     SFReply reply;
  1774.     CharsHandle h;
  1775.     char *oldfName = NULL;
  1776.     short oldvRefNum;
  1777.     static char *tmpfile = "\pTMPxyzzy";
  1778.  
  1779.     if (cmdw->refNum)            /* if existing file open */
  1780.     closefile(cmdw);
  1781.  
  1782.     if (cmdw->fName) {            /* if existing name */
  1783.     oldfName = cmdw->fName;
  1784.     oldvRefNum = cmdw->vRefNum;
  1785.     } else
  1786.     as = TRUE;            /* always treat as Save As */
  1787.  
  1788.     if (as || !oldfName) {        /* if forced or none previous */
  1789.     SetPt (&where, 75, 115);
  1790.     SFPutFile(where, "\pSave As", cmdw->wname,
  1791.             0L, &reply);
  1792.     if (!reply.good)        /* if Cancel */
  1793.         return;
  1794.         /* !!!!! hmmm, we may have closed the file */
  1795.  
  1796.     cmdw->vRefNum = reply.vRefNum;
  1797.     cmdw->fName = malloc_pstring(reply.fName);
  1798.     }
  1799.  
  1800.     /*
  1801.      * Open a temporary file and write our text to it.  Possibly
  1802.      * delete an old tmp file.
  1803.      */
  1804.     FSDelete(tmpfile, cmdw->vRefNum);
  1805.  
  1806.     /* !!!!! should generate unique name here */
  1807.     err = Create(tmpfile, cmdw->vRefNum, kermtype ,texttype);
  1808.     if (err != noErr) {
  1809.     printfalert("Could not create %s: %d", p2c_tmp(tmpfile), err);
  1810.     return;
  1811.     }
  1812.     err = FSOpen(tmpfile, cmdw->vRefNum, &refNum);
  1813.     if (err != noErr) {
  1814.     printfalert("Could not open %s: %d", p2c_tmp(tmpfile), err);
  1815.     return;
  1816.     }
  1817.     cmdw->refNum = refNum;
  1818.  
  1819.     h = TEGetText(cmdw->teh);
  1820.  
  1821.     len = (*cmdw->teh)->teLength;
  1822.     err = FSWrite(cmdw->refNum, &len, (Ptr)*h);
  1823.     if (err != noErr) {
  1824.     printfalert("savefile err writing: %d", err);
  1825.     }
  1826.  
  1827.     err = FSClose(cmdw->refNum);
  1828.     if (err != noErr) {
  1829.     printfalert("Error closing file: %d", err);
  1830.     cmdw->refNum = 0;        /* lose this file */
  1831.     return;
  1832.     }
  1833.  
  1834.     /*
  1835.      * If there was an old file, delete it now unless we're doing
  1836.      * a save as and the new file name is different.
  1837.      */
  1838.     if (oldfName && 
  1839.     (!as || ((oldvRefNum == cmdw->vRefNum) && 
  1840.          strcmp(p2c_tmp(oldfName), p2c_tmp2(cmdw->fName)) == 0))) {
  1841.     err = FSDelete(oldfName, oldvRefNum);
  1842.     if (err != noErr) {
  1843.         printfalert("Error deleting old file %s: %d", 
  1844.             p2c_tmp(oldfName), err);
  1845.         return;
  1846.     }
  1847.     if (oldfName != cmdw->fName)
  1848.         free(oldfName);
  1849.     oldfName = NULL;
  1850.     }
  1851.     /*
  1852.      * Possibly delete the file name we're about to use.
  1853.      * This happens if we are replacing a file.  Hopefully,
  1854.      * the dialog already check to see if this was ok.
  1855.      */
  1856.     FSDelete(cmdw->fName, cmdw->vRefNum);
  1857.  
  1858.     /*
  1859.      * rename our tmp file to be the new file.
  1860.      */
  1861.     err = Rename(tmpfile, cmdw->vRefNum, cmdw->fName);
  1862.     if (err != noErr) {
  1863.     printfalert("Error renaming %s to %s: %d", 
  1864.             p2c_tmp(tmpfile), p2c_tmp2(cmdw->fName), err);
  1865.     return;
  1866.     }
  1867.  
  1868.     /*
  1869.      * Open our new file to keep it locked.
  1870.      */
  1871.     err = FSOpen(cmdw->fName, cmdw->vRefNum, &cmdw->refNum);
  1872.     if (err != noErr) {
  1873.     printfalert("savefile: error re-opening %s: %d",
  1874.             p2c_tmp(cmdw->fName), err);
  1875.     }
  1876.  
  1877.     setwname(cmdw, cmdw->fName);
  1878.     cmdw->flags &= ~CMDWF_MODIFIED;    /* not modified any more */
  1879. }
  1880.  
  1881.  
  1882. /*
  1883.  * checksave
  1884.  * Check to see if we should save a modified buffer.
  1885.  * Return FALSE if cancelled.
  1886.  */
  1887. Boolean checksave (struct cmdw *cmdw)
  1888. {
  1889.     DialogPtr dlg;
  1890.     short itemhit;
  1891.     char scratch[255];
  1892.  
  1893.     if (!(cmdw->flags & CMDWF_MODIFIED) || !(cmdw->flags & CMDWF_FILE))
  1894.     return TRUE;
  1895.  
  1896.     sprintf(scratch, "Save changes to %s", p2c_tmp(cmdw->wname));
  1897.     c2pstr(scratch);
  1898.     ParamText(scratch, "", "", "");
  1899.     dlg = GetNewDialog (SAVEBOXID, NILPTR, (WindowPtr) - 1);
  1900.     circleOK(dlg);
  1901.     
  1902.     for (;;) {
  1903.     ModalDialog ((ModalFilterProcPtr) NILPROC, &itemhit);
  1904.  
  1905.     switch (itemhit) {
  1906.     case SV_YES:
  1907.         DisposDialog(dlg);
  1908.         savefile(cmdw, FALSE);
  1909.         return TRUE;
  1910.  
  1911.     case SV_NO:
  1912.         DisposDialog(dlg);
  1913.         return TRUE;
  1914.  
  1915.     case SV_CANCEL:
  1916.         DisposDialog(dlg);
  1917.         return FALSE;
  1918.     }
  1919.     }
  1920. }
  1921.  
  1922.  
  1923. /*
  1924.  * closetermw
  1925.  * What to do when a termw window is closed
  1926.  */
  1927. closetermw (struct termw *termw)
  1928. {
  1929.     kHideWindow(termw);
  1930.  
  1931.     if (termw == ttermw)
  1932.     kSelectWindow(ctermw->window); /* force command window */
  1933.     else if (termw == ctermw)
  1934.     kSelectWindow(ttermw->window); /* force terminal window */
  1935. }
  1936.  
  1937.  
  1938. /*
  1939.  * setwname
  1940.  * Set window name
  1941.  * name is a pascal string
  1942.  */
  1943. setwname (struct cmdw *cmdw, char *name)
  1944. {
  1945.     struct cmdw *tmp;
  1946.  
  1947.     if (cmdw->wname)
  1948.     free(cmdw->wname);
  1949.     cmdw->wname = malloc_pstring(name);
  1950.     SetWTitle (cmdw->window, cmdw->wname);
  1951.  
  1952.     /*
  1953.      * Don't try to update the Windows menu if we have old roms.
  1954.      */
  1955.     if (!have_128roms)
  1956.     return;
  1957.  
  1958.     /*
  1959.      * Delete old item in Windows menu if it exists and 
  1960.      * renumber following items.
  1961.      */
  1962.     if (cmdw->menuitem) {
  1963.     DelMenuItem(menus[WIND_MENU], cmdw->menuitem);
  1964.  
  1965.     for (tmp = cmdwl; tmp; tmp = tmp->next)
  1966.         if (tmp->menuitem > cmdw->menuitem)
  1967.         tmp->menuitem--;
  1968.     }
  1969.  
  1970.     /*
  1971.      * Insert new window name after the fixed entries.
  1972.      * Renumber other items.
  1973.      */
  1974.     InsMenuItem(menus[WIND_MENU], cmdw->wname, RESP_WIND);
  1975.     for (tmp = cmdwl; tmp; tmp = tmp->next)    
  1976.     if (tmp->menuitem)
  1977.         tmp->menuitem++;
  1978.     cmdw->menuitem = RESP_WIND + 1;
  1979. }
  1980.  
  1981.  
  1982. /*
  1983.  * malloc_pstring
  1984.  * Return a malloced copy of a pascal string.
  1985.  */
  1986. char *malloc_pstring (char *src)
  1987. {
  1988.     char *dst;
  1989.  
  1990.     dst = malloc(src[0]+1);
  1991.     if (!dst)
  1992.     macfatal("malloc_pstring: no memory", 0);
  1993.     bcopy(src, dst, src[0]+1);
  1994.     return dst;
  1995. }
  1996.  
  1997.  
  1998. /*
  1999.  * msignal
  2000.  * signal() replacement function.
  2001.  */
  2002. SIGTYP (*msignal (int type, SIGTYP (*func)(int)))(int)
  2003. {
  2004.     SIGTYP (*old)();
  2005.  
  2006.     if (type == SIGALRM) {
  2007.     old = alarmfunc;
  2008.     alarmfunc = func;
  2009.     } else if (type == SIGINT) {
  2010.     old = intfunc;
  2011.     intfunc = func;
  2012.     } else {
  2013.     macfatal("msignal unknown type", type);
  2014.     }
  2015.  
  2016.     return old;
  2017. }
  2018.  
  2019.  
  2020. /*
  2021.  * malarm
  2022.  * alarm() replacement function
  2023.  */
  2024. void malarm (int value)
  2025. {
  2026.     /*
  2027.      * Save global alarm time
  2028.      */
  2029.     if (value == 0)            /* if clearing the alarms */
  2030.     alarmtime = 0L;
  2031.     else
  2032.     alarmtime = TickCount() + 60L * value;
  2033. }
  2034.  
  2035.  
  2036. /*
  2037.  * msleep
  2038.  * sleep for milliseconds
  2039.  */
  2040. msleep (int delay)
  2041. {
  2042.     ulong ticks;
  2043.  
  2044.     ticks = (delay + 15) / 16;        /* approximate number of ticks */
  2045.     ticks += TickCount();
  2046.  
  2047.     while (((ulong)TickCount() - ticks) < 0)
  2048.     ;
  2049. }
  2050.  
  2051.  
  2052. /*
  2053.  * updatepstat
  2054.  * Update status of various print menus.
  2055.  */
  2056. updatepstat ()
  2057. {
  2058.     if (!hPrintBuffer || !lPrintBufferChars || to_printer) {
  2059.     DisableItem(menus[FILE_MENU], PBUF_FIL);
  2060.     DisableItem(menus[FILE_MENU], PSTAT_FIL);
  2061.     DisableItem(menus[FILE_MENU], PDISC_FIL);
  2062.     } else {
  2063.     EnableItem(menus[FILE_MENU], PBUF_FIL);
  2064.     EnableItem(menus[FILE_MENU], PSTAT_FIL);
  2065.     EnableItem(menus[FILE_MENU], PDISC_FIL);
  2066.     }
  2067.     if (lPrintBufferChars)
  2068.     EnableItem(menus[FILE_MENU], POPEN_FIL);
  2069.     else
  2070.     DisableItem(menus[FILE_MENU], POPEN_FIL);
  2071. }
  2072.  
  2073.  
  2074. /*
  2075.  * doprinter
  2076.  * Print the current window.
  2077.  */
  2078. doprinter (WindowPtr window)
  2079. {
  2080.     long length;
  2081.     CharsHandle h;
  2082.     struct cmdw *cmdw;
  2083.  
  2084.     if (!(cmdw = cmdwbywindow(window))) {
  2085.     SysBeep(3);
  2086.     return;
  2087.     }
  2088.  
  2089.     length = (*cmdw->teh)->teLength;
  2090.     h = TEGetText(cmdw->teh);
  2091.  
  2092.     printer(h, length, 0L, 0x7FFFFFFFL);
  2093. }
  2094.  
  2095.  
  2096. /*
  2097.  * Junk so Emacs will set local variables to be compatible with Mac/MPW.
  2098.  * Should be at end of file.
  2099.  * This routine is formatted for 8 char tabs.
  2100.  * 
  2101.  * Local Variables:
  2102.  * tab-width: 8
  2103.  * End:
  2104.  */
  2105.